﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Extentions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using Senparc.Weixin.MP.Helpers;
using Senparc.Weixin.Open.QRConnect;
using Senparc.Weixin.WxOpen.AdvancedAPIs.WxApp.Business.JsonResult;
using TrainingReminderSystem.Bll;
using TrainingReminderSystem.Model;

namespace TrainingReminderSystem.ApiControllers
{
    /// <summary>
    /// 登录注销模块
    /// 公有
    /// </summary>
    public partial class LoginController : BaseControllerBase
    {
        #region 登录/Token登录/验证码/注销

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="form">form对象</param>
        /// <returns></returns>
        [Route("api/Login/Login")]
        [HttpPost]
        [AllowAnonymous]
        [ExOperateLog(EnumOperateLogType.登录)]
        public AjaxResult<List<LoginInfo>> Login([FromForm] IFormCollection form)
        {
            var bll = new SysEmployeeBll();
            var result = bll.Login(form["uid"], form["pwd"], form["captchaText"]);
            return result;
        }

        /// <summary>
        /// 登录模式2,传参形式不同而已,与Login登录一模一样
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [Route("api/Login/Login2")]
        [HttpPost]
        [AllowAnonymous]
        [ExOperateLog(EnumOperateLogType.登录)]
        public AjaxResult<List<LoginInfo>> Login2(TempLoginClass form)
        {
            var bll = new SysEmployeeBll();
            var result = bll.Login(form.uid, form.pwd, form.captchaText);
            return result;
        }

        /// <summary>
        /// 登录对象
        /// </summary>
        public class TempLoginClass
        {
            public string uid { get; set; }

            public string pwd { get; set; }

            public string captchaText { get; set; }
        }

        /// <summary>
        /// 得到网站基本配置
        /// </summary>
        /// <param name="form">form对象</param>
        /// <returns></returns>
        [Route("api/Login/GetNeedCaptcha")]
        [HttpPost]
        [AllowAnonymous]
        public AjaxResult<SysEmployeeBll.WebConfigInfo> GetNeedCaptcha([FromForm] IFormCollection form)
        {
            var bll = new SysEmployeeBll();
            return bll.GetNeedCaptcha();
        }

        /// <summary>
        /// 创建验证码
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [Route("api/Login/CreateCaptcha")]
        [HttpPost]
        [AllowAnonymous]
        public AjaxResult<string> CreateCaptcha([FromForm] IFormCollection form)
        {
            var bll = new SysEmployeeBll();
            return bll.CreateCaptcha();
        }

        /// <summary>
        /// 根据Token重新获取登录信息
        /// </summary>
        /// <returns></returns>
        [Route("api/Login/LoginByToken")]
        [HttpPost]
        [AllowAnonymous]
        public AjaxResult<LoginInfo> LoginByToken()
        {
            var bll = new SysEmployeeBll();
            var result = bll.LoginByToken(PcLoginedBll.Token);
            return result;
        }

        /// <summary>
        /// 注销
        /// </summary>
        /// <returns></returns>
        [Route("api/Login/LoginOut")]
        [HttpPost]
        [AllowAnonymous]
        [ExOperateLog(EnumOperateLogType.注销)]
        public AjaxResult<SysEmployeeBll.LoginOutResult> LoginOut([FromForm] IFormCollection form)
        {
            var bll = new SysEmployeeBll();
            var r = bll.LoginOut();
            return r;
        }

        #endregion

        #region 微信相关

        /// <summary>
        /// 通过code获取openid
        /// </summary>
        /// <param name="form">[{key:'code',value:''},{key:'EnumOpenIDType',value:0}]</param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("api/Login/GetOpenID")]
        public async Task<AjaxResult<List<LoginInfo>>> GetOpenID([FromForm] IFormCollection form)
        {
            //var sessionID = System.Web.HttpContext.Current.Session.SessionID;
            if (form == null || string.IsNullOrEmpty(form["code"]))
            {
                return AjaxResult<List<LoginInfo>>.ErrorResult("未获取到code值");
            }

            string code = form["code"];
            EnumOpenIDType type = (EnumOpenIDType)form["EnumOpenIDType"].ExToInt32();
            string appid = form["appid"];
            var openIDResult = await WechatHelper.GetOpenID(EnumWxType.管理后台, type, code, appid);
            if (openIDResult.Success == false)
            {
                return AjaxResult<List<LoginInfo>>.ErrorResult(openIDResult.Message);
            }

            var userInfo = openIDResult.Result;
            string session_Key = openIDResult.Message;
            var result = SysEmployeeOpenIDBll.GetWechatToken(userInfo, type, null, session_Key);
            //result.Message = openIDResult.Message;//小程序session_Key
            return result;
        }

        /// <summary>
        /// 得到微信信息,如果有登录信息,则一并返回token
        /// </summary>
        /// <param name="form"></param>
        /// <returns>Message是WechatToken;Result是Token登录信息</returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("api/Login/GetTestOpenID")]
        public AjaxResult<List<LoginInfo>> GetTestOpenID([FromForm] IFormCollection form)
        {
            if (form == null || string.IsNullOrEmpty(form["openID"]))
            {
                return AjaxResult<List<LoginInfo>>.ErrorResult("未获取到openid值");
            }

            string openid = form["openID"];
            EnumOpenIDType enumOpenIDType = (EnumOpenIDType)form["enumOpenIDType"].ExToInt32();
            var userInfo = new Senparc.Weixin.Open.OAuthAPIs.OAuthUserInfo();
            userInfo.openid = openid;
            AjaxResult<List<LoginInfo>> result = SysEmployeeOpenIDBll.GetWechatToken(userInfo, enumOpenIDType, null, null);
            return result;
        }

        /// <summary>
        /// 微信H5用户获取信息链接
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("api/Login/GetAuthorizeUrl")]
        public AjaxResult<string> GetAuthorizeUrl([FromForm] IFormCollection form)
        {
            return WxOpenSdkHelper.GetAuthorizeUrl(EnumWxType.管理后台, form["redirectUrl"], null);
        }

        /// <summary>
        /// 微信H5的JsSdk
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [ExOnlyValidateOpenID]
        [HttpPost]
        [Route("api/Login/WechatJsSdk")]
        public AjaxResult<JsSdkUiPackage> WechatJsSdk([FromForm] IFormCollection form)
        {
            var result = WxOpenSdkHelper.WechatJsSdk(EnumWxType.管理后台, form["url"]);
            return result;
        }

        [ExOnlyValidateOpenID]
        [HttpPost]
        [Route("api/Login/SetUserInfo")]
        public async Task<AjaxResult<string>> SetUserInfo([FromForm] IFormCollection form)
        {
            var result = await WechatHelper.SetUserInfo(form["json"]);
            return result;
        }

        [ExOnlyValidateOpenID]
        [HttpPost]
        [Route("api/Login/GetUserInfo")]
        public AjaxResult<string> GetUserInfo()
        {
            var result = WechatHelper.GetUserInfo();
            return result;
        }

        ///// <summary>
        ///// 微信小程序直接获取手机号并绑定
        ///// </summary>
        ///// <param name="form"></param>
        ///// <returns></returns>
        //[ExOnlyValidateOpenID]
        //[HttpPost]
        //[Route("api/Login/GetPhoneNumber")]
        //public AjaxResult<string> GetPhoneNumber([FromForm] IFormCollection form)
        //{
        //    string sessionKey = CustomerLoginedBll.CurrentOpenID.session_Key;
        //    AjaxResult<string> result = WxOpenSdkHelper.GetPhoneNumber(form["encryptedData"], form["iv"], sessionKey);
        //    if (result.Success == false)
        //    {
        //        var resultTemp = new AjaxResult<string>();
        //        resultTemp.Success = result.Success;
        //        resultTemp.Total = result.Total;
        //        resultTemp.Message = result.Message;
        //        return resultTemp;
        //    }

        //    //var bll = new ShangjiaLoginBll();
        //    //string phone = result.Result;
        //    //form = form.ExAdd("phone", phone);
        //    //var r = bll.Register(form);
        //    //return r;
        //    return result;
        //}

        [ExOnlyValidateOpenID]
        [HttpPost]
        [Route("api/Login/GetUserPhoneNumber")]
        public AjaxResult<GetUserPhoneNumberJsonResult> GetUserPhoneNumber([FromForm] IFormCollection form)
        {
            //var sessionID = System.Web.HttpContext.Current.Session.SessionID;
            if (form == null || string.IsNullOrEmpty(form["code"]))
            {
                return AjaxResult<GetUserPhoneNumberJsonResult>.ErrorResult("未获取到code值");
            }

            string code = form["code"];
            string appid = form["appid"];
            var openIDResult = WechatHelper.GetUserPhoneNumber(EnumWxType.客户端, code, appid);
            if (openIDResult.Success == false)
            {
                return AjaxResult<GetUserPhoneNumberJsonResult>.ErrorResult(openIDResult.Message);
            }

            return openIDResult;
        }

        #region 微信开放平台消息回发

        /// <summary>
        /// 微信模版消息回发
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        [Route("api/Login/TemplateStatus")]
        public AjaxResult<string> TemplateStatus([FromForm] IFormCollection form)
        {
            WechatHelper.TemplateStatus(form["msgID"], form["status"]);
            return AjaxResult<string>.SuccessResult();
        }

        /// <summary>
        /// 扫码回发
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("api/Login/Scan")]
        public AjaxResult<string> Scan([FromForm] IFormCollection form)
        {
            WechatHelper.Scan(form["eventKey"], form["fromUser"]);
            return AjaxResult<string>.SuccessResult();
        }

        #endregion

        #region 网站应用获取微信用户信息

        /// <summary>
        /// 网站应用获取微信用户信息
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("api/Login/GetWebOpenID")]
        public async Task<AjaxResult<List<LoginInfo>>> GetWebOpenID([FromForm] IFormCollection form)
        {
            //var sessionID = System.Web.HttpContext.Current.Session.SessionID;
            if (form == null || string.IsNullOrEmpty(form["code"]))
            {
                return AjaxResult<List<LoginInfo>>.ErrorResult("未获取到code值");
            }

            string code = form["code"];
            EnumOpenIDType type = EnumOpenIDType.微信网站应用;
            var openIDResult = await WechatHelper.GetWebOpenID(code, EnumWxType.管理后台);
            if (openIDResult.Success == false)
            {
                return AjaxResult<List<LoginInfo>>.ErrorResult(openIDResult.Message);
            }
            Senparc.Weixin.Open.OAuthAPIs.OAuthUserInfo userInfo = new Senparc.Weixin.Open.OAuthAPIs.OAuthUserInfo();
            userInfo.openid = openIDResult.Result.openid;
            var result = SysEmployeeOpenIDBll.GetWechatToken(userInfo, type, null, null);
            return result;
        }

        #endregion

        #endregion

        #region 客户端JS报错记录

        /// <summary>
        /// 客户端JS报错记录
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("api/Login/PostError")]
        [AllowAnonymous]
        public AjaxResult<string> PostError([FromForm] IFormCollection form)
        {
            var error = form["error"];
            var other = form["other"];
            if (string.IsNullOrEmpty(error) && string.IsNullOrEmpty(other))
            {
                return AjaxResult<string>.SuccessResult(string.Empty);
            }

            var envPlatform = form["envPlatform"];
            var info = form["info"];
            string currentOther = PcLoginedBll.GetCurrentOther();
            ($"loginInfo:{currentOther}\r\nenvPlatform:{envPlatform},other:{other},envPlatform:{envPlatform},info:{info}\r\nerror:{error}\r\n")
                .ExLogError();
            return AjaxResult<string>.SuccessResult(string.Empty);
        }

        #endregion

        #region 得到所有枚举对象

        private static object _sync = new object();

        /// <summary>
        /// 得到所有枚举对象
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/Login/GetAllEnum")]
        [AllowAnonymous]
        public string GetAllEnum()
        {
            AllEnumBll bll = new AllEnumBll();
            var result = bll.GetAllEnum();
            Task.Run(() =>
            {
                try
                {
                    lock (_sync)
                    {
                        const string cacheKey = "GetAllEnum";
                        bool has = CacheHelper.GetCache<bool?>(cacheKey) ?? false;
                        if (has) return;
                        string jsPath = SysConfig.EnumJsPath;
                        if (string.IsNullOrEmpty(jsPath)) return;
                        //string dir = System.IO.Path.GetDirectoryName(jsPath);
                        //if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir);
                        //检测文件内容与生成的是否一致,一致就不做更改
                        if (System.IO.File.Exists(jsPath))
                        {
                            if (System.IO.File.ReadAllText(jsPath) == result)
                            {
                                CacheHelper.SetRelativeCache(cacheKey, true);
                                return;
                            }
                        }
                        //提示没有权限读取
                        using StreamWriter sw = new StreamWriter(jsPath, System.Text.Encoding.UTF8, new FileStreamOptions()
                        {
                            Access = FileAccess.Write,
                            Mode = FileMode.Create
                        });
                        sw.Write(result);
                        CacheHelper.SetRelativeCache(cacheKey, true);
                    }
                }
                catch (Exception ex)
                {
                }
            });
            return result;
        }

        #endregion
    }
}
